/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package multiversiontechnicaldocumentation;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Multiversion technical document writer to readable format.
 * 
 * White space is not allowed between line start and COMMAND start.
 * (Consequence: COMMANDs cannot be indented.)
 * 
 * @author VadimBaitoiu
 */
public class MVTDWriter extends Writer {

    /**
     *
     * @param document
     * @throws IOException
     */
    @Override
    public void write(Document document) throws IOException {
        SimpleDateFormat sdf = new SimpleDateFormat(DOCUMENT_VERSION_TIME_FORMAT);
        Date date = new Date();
        boolean flag = true;

        for (Document.Version documentVersion : document.getVersionList()) {
            if (flag) {
                flag = false;
            } else {
                this.out.write(NEWLINE);
            }
            this.out.write("VERSION");
            this.out.write(' ');
            date.setTime(documentVersion.getTime());
            this.out.write(sdf.format(date));
            this.out.write(' ');
            this.out.write(documentVersion.getTitle());
            this.out.write(NEWLINE);

            Document.LogicalSection root = documentVersion.getRoot();
            // root logical section is implicit --> do not write logical section command
            Object content = root.getContent();
            if (content instanceof Document.LogicalSection) {
                // handle child logical section
                Document.LogicalSection i = (Document.LogicalSection) content;
                while (i != null) {
                    write(i, 1);
                    i = i.getNext();
                }
            } else {
                String s = "NULL";
                if (content != null) {
                    s = content.getClass().getName();
                }
                this.out.write("ERROR Invalid logical section content type: " + s);
            }
        }
    }

    /**
     *
     * @param logicalSection
     * @param indentationLevel 1..8 (see Document.MAX_DEPTH)
     * @throws IOException
     */
    private void write(Document.LogicalSection logicalSection, int indentationLevel) throws IOException {
        if (indentationLevel > Document.MAX_DEPTH) {
            this.out.write("ERROR Maximum document depth exceeded");
            return;
        }

        this.out.write(NEWLINE);
        this.out.write("LOGICALSECTION");
        this.out.write(' ');
        this.out.write(Long.toString(logicalSection.getID()));
        this.out.write(' ');
        String logicalSectionTitle = logicalSection.getTitle();
        if (logicalSectionTitle == null) {
            logicalSectionTitle = "";
        }
        this.out.write('"' + logicalSectionTitle + '"');
        this.out.write(' ');
        String contentMode = logicalSection.isContentMode() ? "REPLACE" : "COPY";
        this.out.write(contentMode);
        this.out.write(NEWLINE);

        Object content = logicalSection.getContent();
        if (content == null) {
            // 
        } else {
            if (content instanceof Document.LogicalSection) {
                // handle child logical section
                Document.LogicalSection i = (Document.LogicalSection) content;
                while (i != null) {
                    write(i, indentationLevel + 1);
                    i = i.getNext();
                }
            } else {
                if (content instanceof String) {
                    // handle text
                    this.out.write(NEWLINE);
                    String s = (String) content;
                    this.out.write(s);
                    this.out.write(NEWLINE);
                } else {
                    String s = content.getClass().getName();
                    this.out.write("ERROR Invalid logical section content type: " + s);
                }
            }
        }

        this.out.write(NEWLINE);
        this.out.write("LOGICALSECTION");
        this.out.write(NEWLINE);
    }
}
